package com.easyadmin.pro.common.generator;

import com.easyadmin.pro.common.annotation.lock.RequestKeyParam;
import com.easyadmin.pro.common.annotation.lock.RequestLock;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Objects;

/**
 * packageName com.easyadmin.pro.common.generator
 *
 * @author 骑着蚂蚁去上天
 * @version JDK 17
 * @className RequestKeyGenerator
 * @date 2024/9/3
 * @description 生成唯一参数 key
 */
public class RequestKeyGenerator {

    /**
     * 生成
     * @param joinPoint
     * @return
     */
    public static String generator(ProceedingJoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        // 获取方法上的注解
        RequestLock annotation = method.getAnnotation(RequestLock.class);
        StringBuilder sb = new StringBuilder();
        if (Objects.nonNull(annotation)) {
            final Object[] args = joinPoint.getArgs();
            final Parameter[] parameters = method.getParameters();
            int num = 0;
            for (Parameter parameter : parameters) {
                RequestKeyParam requestKeyParam = parameter.getAnnotation(RequestKeyParam.class);
                if (Objects.isNull(requestKeyParam)) {
                    continue;
                }
                sb.append(annotation.delimiter()).append(args[num]);
                num++;
            }
            // 方法上面没有注解
            if (!StringUtils.hasLength(sb.toString())) {
                Annotation[][] parameterAnnotations = method.getParameterAnnotations();
                for (int i = 0; i < parameterAnnotations.length; i++) {
                    final Object object = args[i];
                    final Field[] fields = object.getClass().getDeclaredFields();
                    for (Field field : fields) {
                        RequestKeyParam requestKeyParam = field.getAnnotation(RequestKeyParam.class);
                        if (Objects.isNull(requestKeyParam)) {
                            continue;
                        }
                        field.setAccessible(Boolean.TRUE);
                        sb.append(annotation.delimiter()).append(ReflectionUtils.getField(field, object));
                    }
                }
            }
        }
        return annotation.prefix().concat(sb.toString());
    }
}